﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using log4net;

namespace HttpTunnel
{
    class ResponseSender
    {
        private static readonly ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public static string ErrorPageTemplate { get; private set; }
        public static string OutOfDatePageTemplate { get; private set; }


        public static void Initialize(Config config)
        {
            ErrorPageTemplate = config.ErrorPageTemplate;
            OutOfDatePageTemplate = config.OutOfDatePageTemplate;
        }

        public static void SendBadRequest(Socket socket)
        {
            try
            {
                var html = ErrorPageTemplate.Replace("$HTTPDESC$", "HTTP 400 Bad Request").Replace("$DATETIME$", DateTime.Now.ToString(CultureInfo.CurrentCulture));
                var response = string.Format("HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n{0}", html);
                socket.BeginSend(Encoding.ASCII.GetBytes(response), 0, response.Length, SocketFlags.None, OnErrorSent, socket);
            }
            catch (Exception ex)
            {
                Logger.Debug("SendBadRequest", ex);
                socket.Close();
            }
        }

        public static void SendOutOfDate(Socket socket)
        {
            try
            {
                var html = OutOfDatePageTemplate.Replace("$HTTPDESC$", "HTTP 403 Forbidden").Replace("$DATETIME$", DateTime.Now.ToString(CultureInfo.CurrentCulture));
                var response = string.Format("HTTP/1.1 403 Forbidden\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n{0}", html);
                socket.BeginSend(Encoding.ASCII.GetBytes(response), 0, response.Length, SocketFlags.None, OnErrorSent, socket);
            }
            catch (Exception ex)
            {
                Logger.Debug("SendOutOfDate", ex);
                socket.Close();
            }
        }

        private static void OnErrorSent(IAsyncResult ar)
        {
            var socket = ar.AsyncState as Socket;
            try
            {
                socket.EndSend(ar);
            }
            catch (Exception ex)
            {
                Logger.Debug("OnErrorSent", ex);
            }
            finally
            {
                socket.Close();
            }
        }
    }
}
